// domain.js
// Implement domain redirection.

var DomainStatus = {};
var DomainReady = false;
var DomainReadyCallback = null;

//TODO Provide separate function or optimization for onBeforeRequest when
//matching non-current domains is implemented.
function getRedirectUrl(url)
{
	var domainRegEx = /^([^:]+:\/\/)([^\/]+)/;
	var domain_match = url.match(domainRegEx);
	var domain;
	if(domain_match && (domain = domain_match[2]) &&
		KnownDomains.indexOf(domain) != -1 &&
		domain != Options.Domain.Current)
		return url.replace(domainRegEx, "$1" + Options.Domain.Current);
	else
		return null;
}

function onBeforeRequest(details)
{
	var newUrl;
	if(newUrl = getRedirectUrl(details.url))
		return {redirectUrl: newUrl};
}

function onBeforeNavigate(details)
{
	var newUrl;
	if(details.frameId == 0 && (newUrl = getRedirectUrl(details.url)) )
		chrome.tabs.update(details.tabId, {url: newUrl});
}

function onTabsUpdated(tabId, changeInfo, tab)
{
	var newUrl;
	if(newUrl = getRedirectUrl(changeInfo.url || ""))
		chrome.tabs.update(tabId, {url: newUrl});
}

function CheckDomain(domain, callback)
{
	var url = "http://" + domain + "/thread.php?fid=1";
	XHR.SendRequest(url, (function(xhr)
	{
		DomainStatus[domain] = "ok";
		callback(DomainStatus);
	}), (function(xhr)
	{
		if(xhr.status == 404)
			DomainStatus[domain] = "unavailable";
		else
			DomainStatus[domain] = "error";
		callback(DomainStatus);
	}), {fullUrl: true});
}

Options.Domain.onChanged = (function(item, newValue)
{
	console.log(item, newValue);
	//autoDetect or alwaysExternal
	if(Options.Domain.Preference != "custom")
	{
		if(chrome.webRequest)
		{
			//As a result of the change of Options.Domain.Current
			if(chrome.webRequest.onBeforeRequest.hasListener(
				onBeforeRequest))
				chrome.webRequest.onBeforeRequest.removeListener(
					onBeforeRequest);

			chrome.webRequest.onBeforeRequest.addListener(onBeforeRequest, 
				{urls: DomainMatchPatterns.filter(function(element)
				{
					//Excluding the current domain
					return (element.indexOf(Options.Domain.Current) == -1);
				})}, ["blocking"]);
		}
		else if(chrome.webNavigation && 
			!chrome.webNavigation.onBeforeNavigate.hasListener(
			onBeforeNavigate))
			chrome.webNavigation.onBeforeNavigate.addListener(
				onBeforeNavigate);
		else if(!chrome.tabs.onUpdated.hasListener(onTabsUpdated))
			chrome.tabs.onUpdated.addListener(onTabsUpdated);
	}
	else //custom
	{
		if(chrome.webRequest)
			chrome.webRequest.onBeforeRequest.removeListener(
				onBeforeRequest);
		else if(chrome.webNavigation)
			chrome.webNavigation.onBeforeNavigate.removeListener(
				onBeforeNavigate);
		else
			chrome.tabs.onUpdated.removeListener(onTabsUpdated);
	}
});

function UpdateDetectedDomain()
{
	if(DomainStatus["bbs.stuhome.net"] == "unavailable")
		Options.Domain.Current = 
			Options.Domain.PreferredExternalDomain;
	else if(DomainStatus["bbs.stuhome.net"] == "ok")
		Options.Domain.Current = 
			Options.Domain.PreferredInternalDomain;
	// No changes are made if domain detecting fails or the current 
	// domain is neither 'internal' nor 'external' (custom).
}


function DetectDomain()
{
	CheckDomain("bbs.stuhome.net", function(status)
	{
		if(Options.Domain.Preference == "autoDetect")
			UpdateDetectedDomain();
		DomainReady = true;
		DomainReadyCallback && DomainReadyCallback();
	});
}

DetectDomain();

// *** Options.Domain.Force has been DEPRECATED and should only be used
// here to ensure compatibility with old versions
if(!Options.Domain.Force)
{
	Options.Domain.Force = true; //Set it to true so that the storage item
	// for the option will be removed and the following line will no longer
	// be executed.
	Options.Domain.Preference = "custom";
}

(Options.Domain.Preference != "custom")  && Options.Domain.onChanged();

